package com.gitee.dupe.authority.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gitee.dolt.annotation.security.PreAuth;
import com.gitee.dolt.boot.controller.SuperController;
import com.gitee.dolt.boot.request.QueryParams;
import com.gitee.dolt.core.base.Result;
import com.gitee.dolt.core.util.BizAssert;
import com.gitee.dupe.authority.dto.RoleSaveDTO;
import com.gitee.dupe.authority.entity.Role;
import com.gitee.dupe.authority.extend.AuthorityCustomOperate;
import com.gitee.dupe.authority.service.IRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Set;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author LYH
 * @since 2020-06-30
 */
@RestController
@RequestMapping("/b/role")
@Validated
@Api(value = "Role", tags = "角色")
@RequiredArgsConstructor
@PreAuth(replace = "b:role:")
public class RoleController extends SuperController<Role, IRoleService, Long, RoleSaveDTO, RoleSaveDTO, Role> {

    private final AuthorityCustomOperate authorityCustomOperate;

    @Override
    public boolean enableQuery() {
        return true;
    }

    @Override
    public QueryWrapper<Role> handlerQueryWrapper(Role role, QueryParams<Role> params) {
        QueryWrapper<Role> qw = Wrappers.query();
        String keyword = params.getKeyword();
        if (StrUtil.isNotEmpty(keyword)) {
            qw.lambda().like(Role::getIdent, keyword).or().like(Role::getName, keyword);
        }
        return qw;
    }

    @Override
    public Result handlerSave(RoleSaveDTO roleSaveDTO) {
        Role role = BeanUtil.toBean(roleSaveDTO, Role.class);
        BizAssert.isTrue(baseService.count(Wrappers.<Role>lambdaUpdate()
                .eq(Role::getName, role.getName())) == 0, "角色名称已存在");
        baseService.save(role);
        if (authorityCustomOperate.roleSaveUpdateWithResource()) {
            baseService.grantResources(role.getId(), roleSaveDTO.getResourceIds());
        }
        return Result.ok(role);
    }

    @Override
    public Result handlerUpdate(RoleSaveDTO roleSaveDTO) {
        Role role = BeanUtil.toBean(roleSaveDTO, Role.class);
        BizAssert.isTrue(baseService.count(Wrappers.<Role>lambdaUpdate()
                .eq(Role::getName, role.getName()).ne(Role::getId, role.getId())) == 0, "角色名称已存在");
        baseService.updateById(role);
        if (authorityCustomOperate.roleSaveUpdateWithResource()) {
            baseService.grantResources(role.getId(), roleSaveDTO.getResourceIds());
        }
        return Result.ok(role);
    }

    @PutMapping("/{id}/resources")
    @ApiOperation(value = "角色授予权限")
    @PreAuth("hasPermission('{}grantResources')")
    public Result grantResources(@PathVariable Long id, @RequestBody Set<Long> resourceIds) {
        baseService.grantResources(id, resourceIds);
        return Result.ok();
    }

    @Override
    public Result handlerGet(Long id) {
        return Result.ok(baseService.getDetail(id));
    }

    @Override
    public Result handlerDelete(List<Long> ids) {
        baseService.handlerDelete(ids);
        return Result.ok();
    }
}
